
#include <iostream>
#include "ParseH264.h"
#include "FileHelp.h"
#include "rtp-payload.h"
#include "rtp.h"
#include <assert.h>
#include "pcapParse.h"
#include "EventLoopMgr.h"
#include "AfSocket.h"
#include "NetMgr.h"

struct rtp_sender_t
{
	void* encoder;
	void* rtp;

	int payload;
	char encoding[16];

	uint16_t seq;
	uint32_t ssrc;
	uint32_t timestamp;
	uint32_t frequency; // default video: 90000
	uint32_t bandwidth; // default video: 2Mb, audio: 128Kb

	uint8_t buffer[2 * 1024]; // for sdp and rtp packet

	/// @return 0-ok, other-error
	int (*onpacket)(void* param, const void* packet, int bytes, uint32_t timestamp, int flags);
	void (*onbye)(void* param); // rtcp bye msg
	void* param;

	AfUdpSocket m_rtp;
	AfUdpSocket m_rtcp;
};


uint32_t rtp_ssrc(void);

static void* rtp_alloc(void* param, int bytes)
{
	struct rtp_sender_t* s = (struct rtp_sender_t*)param;
	assert(bytes <= sizeof(s->buffer));
	return s->buffer;
}

static void rtp_free(void* param, void* packet)
{
	struct rtp_sender_t* s = (struct rtp_sender_t*)param;
	assert(s->buffer == packet);
}

static int rtp_packet(void* param, const void* packet, int bytes, uint32_t timestamp, int flags)
{
	struct rtp_sender_t* s = (struct rtp_sender_t*)param;
	assert(s->buffer == packet);

	RTPHeader header;
	bool ret =  rtpParse(header, packet, bytes);

	printf("ssrc:%x seq:%d \n", header.ssrc, header.sequenceNumber);


	printf("rtp_packet bytes:%d \n", bytes);

	s->m_rtp.SendTo(packet, bytes, AfSockAddr("127.0.0.1", 58004));

	int ret1 = rtp_onsend(s->rtp, packet, bytes/*, time*/);
	printf("########## ret1:%d \n", ret1);
	return 0;
#if 0
	int r = s->onpacket(s->param, packet, bytes, timestamp, flags);
	if (0 == r)
		rtp_onsend(s->rtp, packet, bytes/*, time*/);

	return r;
#endif
}

static void rtp_onrtcp(void* param, const struct rtcp_msg_t* msg)
{
	struct rtp_sender_t* s = (struct rtp_sender_t*)param;
	printf("rtp_onrtcp  ... \n");
	if (RTCP_BYE == msg->type && s->onbye)
		s->onbye(param);
}
uint32_t rtp_ssrc(void);


int main()
{

	EventLoopMngr::GetInstance()->Init();
	NetMgr::GetInstance()->Init();


	std::shared_ptr<TaskScheduler> task = EventLoopMngr::GetInstance()->m_oEventLoop.GetTaskScheduler();
	std::shared_ptr<WorkerThreadN> netTask = NetMgr::GetInstance()->m_oEventLoop.GetTaskScheduler();

	rtp_sender_t* s = new rtp_sender_t();

	memset(s, 0, sizeof(rtp_sender_t));
	
	s->payload = 109;
	s->seq = 100;
	s->ssrc = 0x01;
	s->timestamp = 0;
	s->bandwidth = s->bandwidth ? s->bandwidth : 2 * 1024 * 1024; // default 2Mb
	s->frequency = 90000; // default 90MHz


	int ret = s->m_rtp.Open(AfSockAddr("127.0.0.1", 58004), true);
	printf("m_sender ret:%d \n", ret);

	ret = s->m_rtcp.Open(AfSockAddr("127.0.0.1", 58005), true);
	printf("m_receive ret:%d \n", ret);

	struct rtp_event_t event;
	struct rtp_payload_t handler = {
		rtp_alloc,
		rtp_free,
		rtp_packet,
	};


	s->encoder = rtp_payload_encode_create(s->payload, "H264", s->seq, s->ssrc, &handler, s);

	event.on_rtcp = rtp_onrtcp;
	s->rtp = rtp_create(&event, s, s->ssrc, s->timestamp, s->frequency, s->bandwidth, 1);
	//rtp_set_info(s->rtp, "RTSPServer", "a.h264");

	ParseH264 tParseH264;

	ret = tParseH264.Init("test.h264");
	printf("init ret:%d \n", ret);






	int64_t timer0 = task->AddTimer(1000,
		[s] {
			
			char buffer[1500];
			int ret = rtp_rtcp_report(s->rtp, buffer, 1500);

			s->m_rtcp.SendTo(buffer, ret, AfSockAddr("127.0.0.1", 58005));

			printf("########### ... ############@@@@@@@@@@@@@@@ ret:%d \n", ret);

			
			return true;
		});



	ChannelPtr channel = std::make_shared<Channel>(s->m_rtcp.hSock);

	channel->SetReadCallback(std::bind([s]{
		// 收到的rtcp 数据
		char buffer[1500];
		s->m_rtcp.RecvFrom(buffer, 1500, AfSockAddr("127.0.0.1", 58005));
		printf("receive rtcp .... \n");
		
		}));

	channel->EnableReading();

	ret = netTask->UpdateChannel(channel);

	ChannelPtr channel_rtp = std::make_shared<Channel>(s->m_rtp.hSock);

	channel_rtp->SetReadCallback(std::bind([s] {
		// 收到的rtcp 数据
		char buffer[1500];
		s->m_rtp.RecvFrom(buffer, 1500, AfSockAddr("127.0.0.1", 58004));
		printf("receive rtp ..... \n");

		}));

	channel_rtp->EnableReading();

	ret = netTask->UpdateChannel(channel_rtp);



	//int GetAnnexbCompositeNALU(int flags, char*& p, int& len, bool& isKey, int mutBand = 1);
	int k = 0;
	uint32_t timestamp = 0;
	while (1)
	{
		NALU_t* t_Nalu = NULL;
		int ret = tParseH264.GetAnnexbNALU(t_Nalu);

		if (ret < 0)
		{
			break;
		}

		timestamp += 3600;
		rtp_payload_encode_input(s->encoder, (const void*) t_Nalu->buf, t_Nalu->len, timestamp);

	

		printf(" k : %d len: %6d  ", k++, t_Nalu->len);
		printf("nal_unit_type: %x\n", t_Nalu->nal_unit_type);

		printf("########### \n");

		std::this_thread::sleep_for(std::chrono::milliseconds(40));
	}

	getchar();
	std::cout << "Hello World!\n";
}
